package references

import (
	"hi-jvm/instructions/base"
	"hi-jvm/rtda"
	"hi-jvm/rtda/heap"
)

// Fetch field from object
type GET_FIELD struct{ base.Index16Instruction }

func (self *GET_FIELD) Execute(frame *rtda.Frame) {
	cp := frame.Method.Class.ConstantPool
	fieldRef := cp.GetConstant(self.Index).(*heap.FieldRef)
	field := fieldRef.ResolvedField()

	if field.IsStatic() {
		panic("java.lang.IncompatibleClassChangeError")
	}

	stack := frame.OperandStack
	ref := stack.PopRef()

	slotId := field.SlotId
	slots := ref.Fields

	if field.IsInt32() {
		stack.PushInt(slots.GetInt(slotId))
		return
	}

	if field.IsFloat() {
		stack.PushFloat(slots.GetFloat(slotId))
		return
	}

	if field.IsInt64() {
		stack.PushLong(slots.GetLong(slotId))
		return
	}

	if field.IsDouble() {
		stack.PushDouble(slots.GetDouble(slotId))
		return
	}

	if field.IsRef() {
		stack.PushRef(slots.GetRef(slotId))
		return
	}
	// todo
}

